package com.oa.pm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.joneying.common.web.response.Resp;
import com.oa.admin.entity.LeaveApply;
import com.oa.admin.service.ILeaveApplyService;
import com.oa.core.PageResult;
import com.oa.pm.dto.RegistrationListDTO;
import com.oa.pm.entity.Registration;
import com.oa.pm.mapper.RegistrationMapper;
import com.oa.pm.service.IRegistrationService;
import com.oa.pm.vo.RegistrationListVO;
import com.oa.system.entity.User;
import com.oa.system.service.IUserService;
import com.sun.org.apache.regexp.internal.RE;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class RegistrationServiceImpl extends ServiceImpl<RegistrationMapper, Registration> implements IRegistrationService {

    @Autowired
    private RegistrationMapper registrationMapper;

    @Autowired
    private ILeaveApplyService leaveApplyService;

    @Autowired
    private IUserService userService;

    public final Integer signOffHour = 17;

    public final Integer signOffMinute = 30;

    public final Integer leaveEarlyHour = 17;

    public final Integer leaveEarlyMinute = 26;

    public final Integer checkInHour = 8;

    public final Integer checkInMinute = 30;

    @Override
    public Resp add(String userId, String address, Integer form) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        Integer day = calendar.get(Calendar.DATE);
        Integer hour = calendar.get(Calendar.HOUR_OF_DAY);
        Integer minute = calendar.get(Calendar.MINUTE);

        if(hour < 13){
            Registration registration = new Registration();
            registration.setType(1);
            registration.setRegistrationDate(format.parse(format.format(date)));
            registration.setAddress(address);
            registration.setUserId(userId);

            int checkInStatus = checkInHander(hour, minute);
            registration.setStatus(checkInHander(hour, minute));
            registration.setTimeoutMinute(checkInStatus == 2 ? minuteDifference(sdf.parse(sdf.format(date) + " "+signOffHour+":"+signOffMinute+":00"), date): 0);
            registration.setForm(form);

            if(insert(registration)){
                return new Resp().success("登记成功");
            }
        }else{
            Wrapper wrapper = new EntityWrapper();
            wrapper.where("user_id = {0}", userId);
            wrapper.where("DATE_FORMAT(registration_date, '%d') = {0}", day);
            wrapper.where("type = {0}", 1);
            Registration checkin = selectOne(wrapper);

            Registration registration = new Registration();
            registration.setUserId(userId);
            registration.setType(2);
            registration.setRegistrationDate(format.parse(format.format(date)));
            registration.setAddress(address);
            registration.setForm(form);
            if(checkin != null){
                int signOffStatus = signOffHander(hour, minute);
                registration.setStatus(signOffStatus);

                registration.setTimeoutMinute(signOffStatus == 3 ? minuteDifference(date, sdf.parse(sdf.format(date) + " "+signOffHour+":"+signOffMinute+":00")): 0);
                if(insert(registration)){
                    return new Resp().success("登记成功");
                }
            }else{
                // 如果找不到上班卡 打上班卡 查不到请假记录 按旷工处理
                LeaveApply leaveApply = leaveApplyService.selectOne(
                        new EntityWrapper<LeaveApply>()
                                .eq("user_id", userId)
                                .ge("leave_start_time", date)
                                .le("leave_end_time", date)
                );
                if(leaveApply != null){
                    registration.setStatus(signOffHander(hour, minute));
                }else{
                    registration.setType(1);
                    //旷工
                    registration.setStatus(4);
                    registration.setTimeoutMinute(minuteDifference(sdf.parse(sdf.format(date) + " "+checkInHour+":"+checkInMinute+":00"), date));
                }
                if(insert(registration)){
                    return new Resp().success("登记成功");
                }
            }
        }
        return new Resp().failure("登记失败");
    }

    @Override
    public Integer signOffHander(Integer hour, Integer minute){
        if(hour >= signOffHour && minute >= signOffMinute){
            return 1;
        }else if(hour < leaveEarlyHour){
            return 2;
        }else if(hour.equals(leaveEarlyHour) && minute <= leaveEarlyMinute){
            return 2;
        }else{
            return 3;
        }
    }

    @Override
    public Integer checkInHander(Integer hour, Integer minute){
        if(hour <= checkInHour && minute <= checkInMinute){
            return 1;
        }else{
            return 2;
        }
    }

    @Override
    public Integer completionHander(Integer hour, Integer minute){
        // 1旷工 2正常
        if(hour >= checkInHour + 1 && minute >= checkInMinute){
            return 1;
        }else{
            return 2;
        }
    }

    long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
    long nh = 1000 * 60 * 60;// 一小时的毫秒数
    long nm = 1000 * 60;// 一分钟的毫秒数
    long ns = 1000;// 一秒钟的毫秒数


    @Override
    public Integer minuteDifference(Date currTime, Date lastReceiveTime){
        Date date1 = currTime;
        Date date2 = lastReceiveTime;
        long diff = date1.getTime() - date2.getTime();

        long day = diff / nd;// 计算差多少天
        long hour = diff % nd / nh + day * 24;// 计算差多少小时
        long min = diff % nd % nh / nm + day * 24 * 60;// 计算差多少分钟
        long sec = diff % nd % nh % nm / ns;// 计算差多少秒

        try{
            return Integer.valueOf(String.valueOf(min));
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    public PageResult<RegistrationListVO> findRegistrationList(RegistrationListDTO registrationListDTO) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(registrationListDTO.getRegistrationDate());

        Integer day = calendar.get(Calendar.DATE);

        List<RegistrationListVO> registrationListVOS = new ArrayList<>();

        Wrapper userWra = new EntityWrapper<User>().eq("is_deleted", 2);

        if(registrationListDTO.getName() != null){
            userWra.eq("name", registrationListDTO.getName());
        }

        Page page = registrationListDTO.getPage();

        Page<User> users = userService.selectPage(page, userWra);
        users.getRecords().forEach(d -> {
            RegistrationListVO registrationListVO = new RegistrationListVO();
            registrationListVO.setUser(d);

//            Wrapper registrationWrapper = new EntityWrapper();
//            registrationWrapper.where("user_id = {0}", d.getId());
//            registrationWrapper.where("DATE_FORMAT(registration_date, '%d') = {0}", day);

            List<Registration> checkIns = selectList(
                    new EntityWrapper()
                            .where("user_id = {0}", d.getId())
                            .where("DATE_FORMAT(registration_date, '%d') = {0}", day)
                            .eq("type", 1)
                            .orderBy("registration_date", true)
            );
            List<Registration> signOffs = selectList(
                    new EntityWrapper()
                            .where("user_id = {0}", d.getId())
                            .where("DATE_FORMAT(registration_date, '%d') = {0}", day)
                            .eq("type", 2)
                            .orderBy("registration_date", false)
            );

            registrationListVO.setCheckIns(checkIns);
            registrationListVO.setSignOffs(signOffs);

            registrationListVOS.add(registrationListVO);
        });
        return new PageResult<>(registrationListVOS, page);
    }

    @Override
    public RegistrationListVO getMyRegistration(String userId) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());

        Integer day = calendar.get(Calendar.DATE);

        RegistrationListVO registrationListVO = new RegistrationListVO();

//        Wrapper registrationWrapper = new EntityWrapper();
//        registrationWrapper.where("user_id = {0}", userId);
//        registrationWrapper.where("DATE_FORMAT(registration_date, '%d') = {0}", day);

        List<Registration> checkIns = selectList(
                new EntityWrapper()
                        .where("user_id = {0}", userId)
                        .where("DATE_FORMAT(registration_date, '%d') = {0}", day)
                        .eq("type", 1)
                        .orderBy("registration_date", true)
        );
        List<Registration> signOffs = selectList(
                new EntityWrapper()
                        .where("user_id = {0}", userId)
                        .where("DATE_FORMAT(registration_date, '%d') = {0}", day)
                        .eq("type", 2)
                        .orderBy("registration_date", false));


        registrationListVO.setCheckIns(checkIns);
        registrationListVO.setSignOffs(signOffs);

        return registrationListVO;
    }
}
